package client;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import UI.UI;

import dataContracts.FileStatus;
import dataContracts.SharedFile;

public class DownloadClient implements Runnable {
	int serverPort;
	String serverAddress;
	
	Socket socket;
	InputStream binaryReader;
	OutputStream binaryWriter;
	String fileName;
	ClientDirectory directory;
	// by default, assume we are downloading the file
	// TODO: we need a better way to do this...
	public String operation = "download";
	
	public DownloadClient(String fileName, String serverAddress, int serverPort, ClientDirectory directory) {
		this.fileName = fileName;
		this.serverPort = serverPort;
		this.serverAddress = serverAddress;
		this.directory = directory;
	}

	public void run() {
		configureSocket();
		
		String fullPath = directory.config.directoryPath + File.separator + fileName;
		
		if (operation.equals("download")) {
			FileOutputStream fileStream;
			
			try {
				System.out.println("Starting file download: "+ fileName);
				fileStream = new FileOutputStream(fullPath);
				int bytesRead;
				byte[] buffer = new byte[1024];
				while ((bytesRead = binaryReader.read(buffer)) != -1) {
					fileStream.write(buffer, 0, bytesRead);
				}
				fileStream.flush();
				fileStream.close();
				socket.close();
				System.out.println("Finished file download: "+ fileName);
				
				// mark the file as up to date
				SharedFile cf = directory.findOrCreateFile(fileName);
				directory.addFile(cf);
				cf.status = FileStatus.Synchronized;
				
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			} 
		} else {
			// file upload
			FileInputStream fileStream = null;
			System.out.println("Trying upload: "+ fullPath);
			try {
				fileStream = new FileInputStream(fullPath);
				sendBytes(fileStream);
				fileStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void configureSocket() {
		try {
			// create socket, and configure read/write streams
			socket = new Socket(serverAddress, serverPort);
			binaryWriter = socket.getOutputStream();
			binaryReader = socket.getInputStream();
			
			System.out.println("Connected to server: "+ serverAddress + ":" + serverPort);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void sendBytes(FileInputStream fileStream) throws IOException {
		int bytesRead;
		byte[] buffer = new byte[256];
		while ((bytesRead = fileStream.read(buffer)) != -1) {
			binaryWriter.write(buffer, 0, bytesRead);
		}
		socket.shutdownOutput();
	}
}